package com.haiheng.bookmusic.base

import android.Manifest
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.media.AudioManager
import android.os.Bundle
import android.os.Environment
import android.os.Handler
import android.os.SystemClock
import android.util.Log
import android.view.View
import android.view.Window
import android.view.WindowManager
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import chuangyuan.ycj.videolibrary.listener.VideoInfoListener
import chuangyuan.ycj.videolibrary.video.ExoUserPlayer
import chuangyuan.ycj.videolibrary.video.VideoPlayerManager
import com.google.android.exoplayer2.ExoPlaybackException
import com.gzzbjkj.bajiesdk.*
import com.haiheng.voiceandbook.Constants.Companion.ROOT_PATH
import com.haiheng.voiceandbook.download.DownLoadManager
import com.it.bannner.ActivityManager
import com.it.bannner.MyApplication
import com.it.bannner.common.DownRecor
import com.it.bannner.log.LogWriter
import com.it.bannner.utils.PermissionsObserver
import com.it.bannner.utils.RxTimerUtil
import com.it.bannner.view.LoadingDialog
import com.it.bannner.viewmodel.MyViewModel
import com.tbruyelle.rxpermissions.RxPermissions
import kotlinx.coroutines.launch
import layout.PaymentAdapter
import java.io.*
import java.net.URL


abstract class BaseActivity : AppCompatActivity(), Serial2TcpTransferListener, VideoInfoListener {

    val TAG = javaClass.simpleName
    var index = 0
    val playUriList = mutableListOf<String>()
    var cacheUriList: List<DownRecor>? = mutableListOf()
    var adapter: PaymentAdapter? = null
    val viewModel by viewModels<MyViewModel>()


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //Density.setDensity(getApplication(), this)
        //  get bajie sdk transfer instance
        initTimeTask()
        initDevice()

        window.setFlags(
            WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN
        )
        hideBottomUIMenu()
        intiLayout()
        initBaseView()
        initView()
        initDataChange()


    }

    var connect = false

    private fun initTimeTask() {
        RxTimerUtil.interval(60 * 60 * 1000, {
            LogWriter.e("1小时刷新一次")
            getDeviceInfo()
            getVideoInfo()


        })
    }

    abstract fun initDataChange()

    private fun initBaseView() {
        val files = File(ROOT_PATH)
        val leng = files.list()
        if (leng == null || leng.size <= 0) {
            lifecycleScope.launch {
                viewModel!!.deleteAll()
                initPer()
            }

        } else {
            initPer()
        }


    }

    private fun initPer() {
        VideoPlayerManager.getInstance().serEnableHintGPRS(true)

        RxPermissions.getInstance(this).request(
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.READ_PHONE_STATE //定位权限

        ).subscribe(object : PermissionsObserver() {
            override fun onGetPermissionsSuccess() {
            }

            override fun onGetPermissionsSuccessFailuer() {
                finish()
            }
        })
    }


    /**
     * 初始视图
     */
    abstract fun initView()

    /**
     * 设置布局
     *
     * @return
     */
    abstract fun intiLayout()


    private var loadingDialog //加载提示框
            : LoadingDialog? = null


    open fun getLoadingDialog(): LoadingDialog {
        if (null == loadingDialog) {
            loadingDialog = LoadingDialog(this)
            //点击空白处Dialog不消失
            loadingDialog!!.setCanceledOnTouchOutside(false)
        }
        return loadingDialog!!
    }

    open fun showLoadingDialog() {
        getLoadingDialog().showDialog()
    }

    open fun hideLoadingDialog() {
        getLoadingDialog().dismiss()
    }

    override fun updateApkV2(p0: String?, p1: String?, p2: String?) {

    }

    override fun onBackPressed() {
        //使用播放返回键监听
        if (exoPlayerManager != null) {
            if (exoPlayerManager!!.onBackPressed()) {
                finish();
            }
        }

    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        exoPlayerManager?.onConfigurationChanged(newConfig);//横竖屏切换
        super.onConfigurationChanged(newConfig)
    }

    override fun onPause() {
        exoPlayerManager?.onPause();
        super.onPause()

    }

    override fun onResume() {
        exoPlayerManager?.onResume()
        super.onResume()
    }


    /**
     * 同步数据
     */
    fun sysData() {
        lifecycleScope.launch {
            deleteOldData()
            addNewData()
            downLoadNewData()

        }


    }

    /**
     * 开启线程池下载新数据
     */
    suspend fun downLoadNewData() {
        val downLoadList = mutableListOf<String>()
        playUriList.forEach {
            val array = it.split("/")
            val name = array[array.size - 1]
            val result = viewModel?.queryListByName(name)
            val file = File(ROOT_PATH, name)
            if (result == null || result.downed == 0 || (!file.exists())) {
                downLoadList.add(it)
            }
            if (downLoadList.size > 0) {
                DownLoadManager.getInstance().startDownLoadTask(downLoadList)
            }

        }
    }

    /**
     * 清理历史的数据
     */
    suspend fun deleteOldData() {
        //清理掉无用的文件
        val fir = File(ROOT_PATH)
        val files = fir.listFiles()
        //已经存在的文件名集合
        val exitNameList = mutableListOf<String>()
        if (files.size > 0) {
            files.forEach {
                val array = it.absolutePath.split("/")
                val name = array[array.size - 1]
                exitNameList.add(name)
            }
        }
        //查询到的名字集合
        val newNameList = mutableListOf<String>()
        playUriList.forEach {
            val array = it.split("/")
            val name = array[array.size - 1]
            newNameList.add(name)
        }
        LogWriter.e("exitNameList: ${exitNameList}")
        LogWriter.e("newNameList: ${newNameList}")
        //求出历史数据
        if (newNameList.size > 0 && exitNameList.size > 0) {
            //求差集
            exitNameList.removeAll(newNameList)
            LogWriter.e("exitNameList - newNameList: ${exitNameList}")
            //清理旧数据
            if (exitNameList.size > 0) {

                exitNameList.forEach {
                    val file = File(ROOT_PATH, it)
                    file.delete()
                    LogWriter.e("删除文件: ${file}")
                    val data = viewModel?.queryListByName(it)
                    if (data != null) {
                        viewModel?.deleteRecord(data)
                        LogWriter.e("删除数据库: ${data}")
                    }
                }

            }

        }

    }

    /**
     * 添加新数据
     */
    fun addNewData() {
        //将所有的记录插入到数据库
        playUriList.forEach { url ->
            val array = url.split("/")
            val name = array[array.size - 1]
            val path = "${ROOT_PATH}/${name}"
            val id = name.split(".")[0].toLong()
            LogWriter.e("sysData: id =  ${id}")
            val record =
                DownRecor(id, name, url, path, 0)
            viewModel!!.addRecord(record)
        }
    }

    //type (1-小屏，2-大屏)
    val type = 1
    var intentService: Intent? = null
    val paymentList = mutableListOf<String>()
    var exoPlayerManager: ExoUserPlayer? = null


    private fun getDeviceInfo() {
        LogWriter.e("getDeviceInfo: ----------------")
        if (mCode != null && mType != null) {
            viewModel?.getDeviceInfo(mCode!!, mType!!)
        }
    }

    private fun getVideoInfo() {
        LogWriter.e("getVideoInfo: ----------------")
        /**
         * 获取视频
         */
        var type = 0
        if (TAG == "MainActivity" || TAG == "MainBlueActivity") {
            type = 1
            viewModel?.getVideo(type, mCode!!)
        }
        if (TAG == "MainLanActivity") {
            type = 2
            viewModel?.getVideo(type, mCode!!)
        }
        if (TAG == "MainLanBigActivity") {
            type = 3
            viewModel?.getVideo(type, mCode!!)
        }
    }

    /**初始化设备相关的
     *
     */
    private var mSerial2TcpTransfer: Serial2TcpTransfer? = null
    private var mSerial2TcpTransferBJH: Serial2TcpTransferBJH? = null
    private var mSerial2TcpTransferBJU: Serial2TcpTransferBJU? = null

    private fun initDevice() {
        BajieSdk.initialize(MyApplication.getInstance())
        // intentService = Intent(applicationContext, TcpTransferService::class.java)
        //startService(intentService)
        val serial2TcpTransfer = BajieSdk.getInstance()
        if (serial2TcpTransfer is Serial2TcpTransfer) {
            mSerial2TcpTransfer = serial2TcpTransfer
        }
        if (serial2TcpTransfer is Serial2TcpTransferBJH) {
            mSerial2TcpTransferBJH = serial2TcpTransfer
        }
        if (serial2TcpTransfer is Serial2TcpTransferBJU) {
            mSerial2TcpTransferBJU = serial2TcpTransfer

        }

        mSerial2TcpTransfer?.setSerial2TcpTransferListener(this)
        mSerial2TcpTransferBJH?.setSerial2TcpTransferListener(this)
        mSerial2TcpTransferBJU?.setSerial2TcpTransferListener(this)

    }


    override fun onPlayStart(currPosition: Long) {
        LogWriter.e("onPlayStart:")
    }


    override fun onLoadingChanged() {
        LogWriter.e("onLoadingChanged:")
    }

    override fun onPlayerError(e: ExoPlaybackException?) {
        LogWriter.e("onPlayerError:${e}")
        index++
        if (playUriList.size > 0) {
            if (index == playUriList.size) {
                index = 0
            }
        } else {
            cacheUriList?.let {
                if (index == it.size) {
                    index = 0
                }
            }

        }


        tryPlay()
    }

    override fun onPlayEnd() {
        LogWriter.e("onPlayEnd:")
        index++
        if (playUriList.size > 0) {
            if (index == playUriList.size) {
                index = 0
            }
        } else {
            cacheUriList?.let {
                if (index == it.size) {
                    index = 0
                }
            }

        }


        tryPlay()


    }

    abstract fun tryPlay()

    /**
     * 设备相关的接口
     */
    override fun receiveSerialData(p0: String?) {
        LogWriter.e("receiveSerialData: ${p0}")
        if (!ActivityManager.getInstance().isForeground) {
            //应用不在前台就重启
        }


    }

    abstract fun updateId(id: String?)

    override fun receiveTcpData(p0: String?) {

    }

    override fun processMessage(p0: String?, p1: String?) {

    }

    var mCode: String? = null
    var mType: Int? = null

    /**
     * 设备ID更新，获取设备信息
     */
    override fun updateDeviceId(p0: String?) {
        updateId(p0)
        LogWriter.e("updateDeviceId: ${p0}")
        var type = 0
        //设备ID更新了，就去获取设备信息
        if (TAG == "MainActivity" || TAG == "MainBlueActivity") {
            type = 1
            p0?.let {
                mCode = it
                mType = type

                getDeviceInfo()
                getVideoInfo()

            }
        }
        if (TAG == "MainLanActivity") {
            type = 2
            p0?.let {
                mCode = it
                mType = type
                getDeviceInfo()
                getVideoInfo()
            }
        }
        if (TAG == "MainLanBigActivity") {
            type = 3
            p0?.let {
                mCode = it
                mType = type
                getDeviceInfo()
                getVideoInfo()
            }
        }


    }

    override fun updateQrCode(p0: String?) {

    }

    override fun initPosConnectType(p0: String?) {

    }

    override fun updateAudio(p0: Int) {

    }

    override fun updateApk(p0: String?, p1: String?) {

    }

    override fun updateImage1(p0: String?, p1: String?, p2: String?) {

    }

    override fun updateImage2(p0: String?, p1: String?, p2: String?) {

    }

    override fun updateImage3(p0: String?, p1: String?) {

    }

    override fun updateMovie(p0: String?, p1: String?) {

    }

    override fun updateWiFiConfig(p0: String?) {

    }

    override fun registerServerConnectFail(p0: String?) {

    }

    override fun communicationServerConnectFail(p0: String?) {

    }


    override fun outPutlog(p0: String?) {

    }

    override fun nettyClosed() {
    }

    override fun appReboot() {
        LogWriter.e("appReboot: ")
        runOnUiThread {
            rebootApp()
        }
    }

    fun rebootApp() {
        val intent = packageManager.getLaunchIntentForPackage(application.packageName)
        val restartIntent = PendingIntent.getActivity(applicationContext, 0, intent, 0)
        val mgr = getSystemService(Context.ALARM_SERVICE) as AlarmManager
        mgr[AlarmManager.RTC, System.currentTimeMillis() + 5000] = restartIntent // 1秒钟后重启应用
        System.exit(0)
    }

    protected open fun hideBottomUIMenu() {
        //隐藏虚拟按键，并且全屏
        window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
        val _window: Window = window
        val params: WindowManager.LayoutParams = _window.getAttributes()
        params.systemUiVisibility =
            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE
        _window.setAttributes(params)
    }

    /**
     * 设置音量
     */
    open fun setAudio(curVolume: Int?) {
        try {
            LogWriter.e("设置音量开始${curVolume}: ")
            curVolume?.let {
                var v = it
                Thread { // 调节音量
                    val audioMgr = getSystemService(AUDIO_SERVICE) as AudioManager
                    // 获取最大音乐音量
                    val maxVolume = audioMgr
                        .getStreamMaxVolume(AudioManager.STREAM_MUSIC)
                    if (v > maxVolume) {
                        v = maxVolume
                    }
                    if (v < 0) {
                        v = 0
                    }
                    audioMgr.setStreamVolume(
                        AudioManager.STREAM_MUSIC, v,
                        AudioManager.FLAG_PLAY_SOUND
                    )
                    SystemClock.sleep(200)
                    LogWriter.e("设置音量结束${curVolume}: ")
                }.start()
            }

        } catch (e: Exception) {
            LogWriter.e("设置音量异常:${e} ")
        }

    }

//    /**
//     * root下静默安装
//     */
//    open fun rootInstallApk(file: File) {
//        LogWriter.e("静默安装开始... ${file}")
//        val printWriter: PrintWriter
//        var process: Process? = null
//        try {
//            process = Runtime.getRuntime().exec("su")
//            printWriter = PrintWriter(process.outputStream)
//            //            printWriter.println("pm install -r " + file.toString()+"; reboot");
//            printWriter.println("pm install -r $file; am start -n com.it.bannner/com.it.bannner.SplashActivity")
//            LogWriter.e("com.it.bannner/com.it.bannner.SplashActivity")
//            printWriter.flush()
//            printWriter.close()
//
//            process.waitFor()
//            LogWriter.e("静默安装完成.. ")
//        } catch (e: java.lang.Exception) {
//            e.printStackTrace()
//            LogWriter.e("静默安装异常...${e.message}")
//        } finally {
//            LogWriter.e("静默安装finally结束... ")
//            process?.destroy()
//        }
//    }

    /**
     * root下静默安装
     */
    open fun rootInstallApk(apkPath: String) {
        LogWriter.e("静默安装开始... ${apkPath}")
        val cmd1 = "am start -n com.it.bannner/com.it.bannner.SplashActivity"
        val cmd2 = "pm install -r $apkPath && "
        val cmd = cmd2 + cmd1
        //Runtime对象
        val runtime = Runtime.getRuntime()
        try {
            val localProcess = runtime.exec("su")
            val localOutputStream = localProcess.outputStream
            val localDataOutputStream = DataOutputStream(localOutputStream)
            localDataOutputStream.writeBytes(cmd)
            localDataOutputStream.flush()
            LogWriter.e("静默安装完成.. ")
        } catch (e: Exception) {
            e.printStackTrace()
            LogWriter.e("静默安装异常...${e.message}")
            e.printStackTrace()
        }
    }

    fun getVersionCode(): Int {
        // 获取packagemanager的实例
        val packageManager = packageManager
        // getPackageName()是你当前类的包名，0代表是获取版本信息
        val packInfo = packageManager.getPackageInfo(packageName, 0)
        LogWriter.e("当前系统的版本号${packInfo.versionCode} ")
        return packInfo.versionCode
    }

    fun getVersionName(): String {
        // 获取packagemanager的实例
        val packageManager = packageManager
        // getPackageName()是你当前类的包名，0代表是获取版本信息
        val packInfo = packageManager.getPackageInfo(packageName, 0)
        LogWriter.e("当前系统的版本名字${packInfo.versionName} ")
        return packInfo.versionName
    }

    /**
     * 开始下载任务
     */
    fun startDownLoadApkTask(path: String) {

        //执行任务，最多执行核心线程数8，最大线程数8
        MyApplication.getInstance().executorUpdate.execute {
            downLoad(path)

        }


    }

    /**
     * 下载
     */
    private fun downLoad(path: String) {
        try {

            LogWriter.e("APK正在下载${path}")
            val url = URL(path)
            val connection = url.openConnection()
            connection.connect()
            val input: InputStream = BufferedInputStream(url.openStream())
            writeFileToDisk(input, "a.apk")

        } catch (e: Exception) {
            LogWriter.e("APK 下载异常: ${e}")
            Handler().postDelayed({
                LogWriter.e("5分之后重新刷新")
                viewModel?.getDeviceInfo(mCode!!, mType!!)
            }, 5 * 60 * 1000)
        }


    }

    /**
     * 将文件 写入磁盘
     */
    fun writeFileToDisk(input: InputStream, name: String) {

        LogWriter.e("APK 开始写入文件 ${name}")
        Log.e(javaClass.simpleName, "开始写入文件")
        val apkPath = Environment.getExternalStorageDirectory().absolutePath + "/APK"
        val fileDir = File(apkPath)
        if (!fileDir.exists()) {
            fileDir.mkdirs()
        }
        val file = File(apkPath + "/${name}")
        if (!file.exists()) {
            file.createNewFile()
        }
        try {
            val fos = FileOutputStream(file)
            val bis = BufferedInputStream(input)
            val buffer = ByteArray(1024)
            var len: Int
            var total: Long = 0
            while ((bis.read(buffer).also { len = it } != -1)) {
                Log.e(javaClass.simpleName, "正在写入文件${len}")
                fos.write(buffer, 0, len)
                total += len
            }
            fos.flush()
            fos.close()
            bis.close()
            input.close()
            Log.e(javaClass.simpleName, "写入文件完毕")
            LogWriter.e("APK 写入文件完毕${Thread.currentThread().name},${file.absolutePath}")
            rootInstallApk(file.absolutePath)
        } catch (e: Exception) {
            Log.e(javaClass.simpleName, "写入文件异常")
            LogWriter.e("APK 写入文件异常: ${e}")
            Handler().postDelayed({
                LogWriter.e("5分之后重新刷新")
                viewModel?.getDeviceInfo(mCode!!, mType!!)
            }, 5 * 60 * 1000)
        }
    }


}